# barco/srcrepos.py


import os
import sys
import pysvn

from . import error
from . import sandboxmoduledesc

class Client(object):

    @staticmethod
    def printm(message, newline=True):
        sys.stdout.write(message)
        if newline: sys.stdout.write('\n')
        sys.stdout.flush()
        return None
    
    @staticmethod
    def print_done(msg=''):
        Client.printm('%sdone.' % msg)
        return None

    @staticmethod
    def print_error(msg=''):
        Client.printm('%sERROR.' % msg)
        return None  

    class WorkSpace(object):
        
        def __init__(self, url, client, directory, branch):
            self.url = url
            self.client = client
            self.branch = branch
            if (os.path.isabs(directory)): 
                self.directory = directory
            else:
                self.directory = os.path.join(os.getcwd(), directory)
            self.updated_dirs = list()
            return None

        def create(self):
            Client.printm('creating workspace on \"%s\" in \"%s\": ' % (self.branch, self.directory), newline=False)
            try:
                self.client.checkout('%s/%s' % (self.url, self.branch), self.directory, depth=pysvn.depth.empty)
                Client.print_done(' ')
            except pysvn.ClientError as e:
                Client.print_error()
                raise e
            return self

        def update(self):
            Client.printm('updating workspace on \"%s\" in \"%s\": ' % (self.branch, self.directory), newline=False)
            Client.print_done()
            return self

        def checkout_directory(self, directory):
            if directory == '': return None
            self.checkout_directory(os.path.dirname(directory))
            Client.printm('checkout directory \"%s\": ' % (directory), newline=False)
            if directory not in self.updated_dirs: 
                self.client.update(os.path.join(self.directory, directory), depth=pysvn.depth.empty)
                self.updated_dirs.append(directory)
                Client.print_done(' ')
            else:
                Client.printm('skip.')
            return None

        def checkout_module(self, module):
            self.checkout_directory(os.path.dirname(module))
            Client.printm('checkout module \"%s\": ' % (module), newline=False)
            m = os.path.join(self.directory, module)
            self.client.update(m, depth=pysvn.depth.infinity, depth_is_sticky=True)
            Client.print_done(' ')
            return None

        def update_directory(self, directory):
            if directory == '': return None
            self.update_directory(os.path.dirname(directory))
            Client.printm('update directory \"%s\": ' % (directory), newline=False)
            if directory not in self.updated_dirs:
                d = os.path.join(self.directory, directory)
                if (not os.path.exists(d)):
                    self.client.update(d, depth=pysvn.depth.empty)
                    self.updated_dirs.append(directory)
                    Client.print_done(' ')
                else:
                    Client.printm('skip.')                   
            else:
                Client.printm('skip.')
            return None        

        def update_module(self, module):
            self.update_directory(os.path.dirname(module))
            Client.printm('update module \"%s\": ' % (module), newline=False)
            m = os.path.join(self.directory, module)
            self.client.update(m, depth=pysvn.depth.infinity, depth_is_sticky=True)
            Client.print_done(' ')
            return None

        def read_module_desc(self, module):
            Client.printm('reading module description \"%s\" from ' % module, newline=False)
            desc_file = os.path.join(self.directory, module, 'moduledesc.py')
            if (os.path.exists(desc_file)):
                Client.printm('local source (after update): ', newline=False)
                self.client.update(desc_file)
                f = open(desc_file, 'rU')
                data = f.read()
                f.close()
                Client.print_done()
            else:
                Client.printm('remote source: ', newline=False)
                data = self.client.cat(os.path.join(self.url, self.branch, module, 'moduledesc.py'))
                Client.print_done()
            return sandboxmoduledesc.SandboxModuleDescription(module, data)
            
        def has_module_desc(self, module):
            desc_file = os.path.join(self.directory, module, 'moduledesc.py')
            if (os.path.exists(desc_file)): return True
            try:
                self.client.cat(os.path.join(self.url, self.branch, module, 'moduledesc.py'))
                return True;
            except:
                pass
            return False

    def __init__(self):
        self.url = 'https://inabox-srcrepos.googlecode.com/svn'
        self.client = pysvn.Client()
        self.client.callback_get_login = self.get_login
        self.client.callback_notify = self.notify
        return None

    def get_login(self, realm, username, save):
        print 'xxxxx'
        return (True, 'wim.vandamme@inabox.be', 'zU3Gu3fw5hs2', save)
    
    def notify(self, event):
        
        # SVN update actions
        if event['action'] == pysvn.wc_notify_action.update_add:
            if event['kind'] == pysvn.node_kind.file:
                self.printm('*', newline=False)
                return None
            if event['kind'] == pysvn.node_kind.dir:
                self.printm('*', newline=False)
                return None
            return None

        return None

    def create_workspace(self, directory, branch):
        return Client.WorkSpace(self.url, self.client, directory, branch).create()

    def update_workspace(self, directory, branch):
        return Client.WorkSpace(self.url, self.client, directory, branch).update()

